Black & Litterman Estimator#
Data#
from plotly.io import show
from sklearn.model_selection import train_test_split
from skfolio import Population, RiskMeasure
from skfolio.datasets import load_sp500_dataset
from skfolio.optimization import MeanRisk, ObjectiveFunction
from skfolio.preprocessing import prices_to_returns
from skfolio.prior import BlackLitterman
prices = load_sp500_dataset()
X = prices_to_returns(prices)
X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)
X_train.head()
| AAPL | AMD | BAC | BBY | CVX | GE | HD | JNJ | JPM | KO | LLY | MRK | MSFT | PEP | PFE | PG | RRC | UNH | WMT | XOM | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Date | ||||||||||||||||||||
| 1990-01-03 | 0.007576 | -0.030303 | 0.008045 | 0.118056 | -0.016229 | -0.001876 | 0.003581 | 0.004072 | 0.033589 | -0.014318 | 0.000000 | 0.015896 | 0.005208 | -0.009709 | 0.002938 | -0.001813 | 0.0 | -0.019355 | 0.000000 | -0.010079 |
| 1990-01-04 | 0.003759 | -0.015500 | -0.021355 | -0.012422 | -0.012831 | -0.005639 | 0.006244 | 0.002028 | 0.003991 | -0.004993 | -0.005557 | -0.015647 | 0.028497 | -0.009804 | 0.016602 | -0.019725 | 0.0 | -0.009868 | -0.005201 | -0.009933 |
| 1990-01-05 | 0.003745 | -0.031996 | -0.021821 | 0.000000 | -0.014855 | -0.009452 | -0.013298 | -0.010408 | 0.003975 | -0.008212 | -0.010874 | -0.020641 | -0.025189 | -0.013991 | -0.008646 | -0.018004 | 0.0 | -0.043189 | -0.010732 | -0.005267 |
| 1990-01-08 | 0.003731 | 0.000000 | 0.005633 | -0.075472 | 0.009424 | 0.005725 | -0.009883 | 0.016944 | 0.000000 | 0.021159 | 0.000000 | 0.012839 | 0.015504 | 0.018118 | -0.008721 | 0.018334 | 0.0 | -0.020833 | 0.013630 | 0.015381 |
| 1990-01-09 | -0.007435 | 0.016527 | 0.000000 | 0.000000 | -0.007469 | -0.020803 | -0.026316 | -0.031026 | -0.031957 | -0.007658 | -0.011147 | -0.007893 | -0.002545 | -0.013722 | -0.021505 | 0.000000 | 0.0 | -0.024823 | -0.026619 | -0.020114 |
Prior View#
prior_view = [
"AAPL == 0.003"
]
Black-Litterman Model#
Maximum Sharpe Ratio with Black-Litterman Estimator
max_sharpe_model_bl = MeanRisk(
risk_measure=RiskMeasure.VARIANCE,
objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
prior_estimator=BlackLitterman(views=prior_view), # Impose prior
portfolio_params=dict(name="Black-Litterman")
)
max_sharpe_model_bl.fit(X_train)
max_sharpe_model_bl.weights_
array([0.62267776, 0.01982462, 0.01976329, 0.01981544, 0.01988257,
0.01986179, 0.01986453, 0.01987279, 0.01978561, 0.0198974 ,
0.01988095, 0.01988681, 0.01988106, 0.01989788, 0.01988813,
0.01988705, 0.0198046 , 0.01985367, 0.01988082, 0.01989322])
Create a vanilla Maximum Sharpe Ratio model.
benchmark_model = MeanRisk(
risk_measure=RiskMeasure.VARIANCE,
objective_function=ObjectiveFunction.MAXIMIZE_RATIO,
portfolio_params=dict(name="Empirical")
)
benchmark_model.fit(X_train)
benchmark_model.weights_
array([9.43631399e-02, 1.13184579e-06, 5.04970598e-07, 1.20834667e-01,
3.18126275e-02, 8.57806907e-07, 7.11596802e-04, 1.24104939e-01,
9.49223801e-07, 2.77547553e-02, 1.23409042e-06, 1.37593860e-06,
1.16299875e-01, 5.73516411e-02, 9.58498590e-06, 1.09493919e-01,
8.64761638e-02, 1.83992252e-01, 1.32350165e-02, 3.35537683e-02])
Prediction#
pred_black_litterman = max_sharpe_model_bl.predict(X_train)
pred_benchmark = benchmark_model.predict(X_train)
Analysis#
population = Population([pred_black_litterman, pred_benchmark])
population.plot_cumulative_returns()
population.plot_composition()
population.plot_returns_distribution()